package org.lex.net.ftp.parser;

import java.util.Calendar;

import org.lex.net.ftp.FTPFile;
import org.lex.utils.text.Chars;
import org.lex.utils.text.Splitter;


public class DefaultFTPFileParser implements FTPFileParser {
	private static final String[] MonthName = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };
	private static Calendar calendar = Calendar.getInstance();
	private static int year = calendar.get(Calendar.YEAR);

	public FTPFile parse(String line) {
		if (null == line || 0 == line.length())
			return null;
		String[] tokens = Splitter.BlankSpaceSplitter.split(line);
		if (tokens.length < 9 || ".".equals(tokens[8]) || "..".equals(tokens[8]))
			return null;
		// start parse
		int timeIndex = Chars.indexOf(line, tokens[7]);
		int fileNameIndex = Chars.indexOf(line, tokens[8], timeIndex + tokens[7].length());
		String name = line.subSequence(fileNameIndex, line.length()).toString();
		long date = parseDateTime(tokens[5], tokens[6], tokens[7]);
		String attribute = tokens[0];
		boolean isDirectory = false;
		long size = 0;
		if ('d' == tokens[0].charAt(0)) {
			isDirectory = true;
		} else {
			isDirectory = false;
			size = Long.parseLong(tokens[4]);
		}
		return new FTPFile("", name, size, date, attribute, isDirectory);
	}

	private long parseDateTime(String month, String day, String value) {
		calendar.set(Calendar.MONTH, 0);
		for (int i = 0; i < 12; i++)
			if (MonthName[i].equalsIgnoreCase(month)) {
				calendar.set(Calendar.MONTH, i);
				break;
			}
		calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day));
		int index = value.indexOf(':');
		if (-1 == index) {
			// "value" is a YEAR field
			calendar.set(Calendar.YEAR, Integer.parseInt(value));
		} else {
			// "value" is a Time field, hh:mm
			calendar.set(Calendar.YEAR, year);
			calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(value.substring(0, index)));
			calendar.set(Calendar.MINUTE, Integer.parseInt(value.substring(index + 1)));
		}
		return calendar.getTimeInMillis();
	}
}
